import os
import threading
import random
import logging
import time
import queue
import datetime
from concurrent.futures import ThreadPoolExecutor

# 配置日志模块
logging.basicConfig(
    level=logging.INFO,
    format="%(asctime)s - [%(threadName)s] - %(levelname)s: %(message)s",
    datefmt="%Y-%m-%d %H:%M:%S",
    handlers=[
        logging.FileHandler("sensor_data.log"),
        logging.StreamHandler()
    ]
)

# 创建线程锁，确保文件写入安全
file_lock = threading.Lock()

# 数据范围定义
data_ranges = {
    "valid_pulse": (60, 100),
    "valid_oxygen": (95, 100),
    "generated_pulse": (50, 120),
    "generated_oxygen": (92, 100)
}

# 数据验证函数
def validate_sensor_data(pulse, oxygen):
    valid = True
    err_pulse = None
    err_oxy = None

    if not (data_ranges["valid_pulse"][0] <= pulse <= data_ranges["valid_pulse"][1]):
        err_pulse = pulse
        valid = False
    if not (data_ranges["valid_oxygen"][0] <= oxygen <= data_ranges["valid_oxygen"][1]):
        err_oxy = oxygen
        valid = False

    return valid, err_pulse, err_oxy

# 数据生成函数
def generate_sensor_readings(file_path, log_queue, tag, running_flag, pause_flag):
    last_pulse = None  # 上一次的脉搏值
    last_oxygen = None  # 上一次的血氧值

    while running_flag[0]:
        if not pause_flag[0]:  # 检查是否暂停
            # pulse
            if last_pulse is None:  # 初始化脉搏值
                pulse = random.uniform(data_ranges["valid_pulse"][0], data_ranges["valid_pulse"][1])
            else:
                # 平滑变化：基于上一次值，增加小范围随机波动
                pulse = last_pulse + random.uniform(-2, 2)
                pulse = max(data_ranges["generated_pulse"][0], min(data_ranges["generated_pulse"][1], pulse))

            # oxygen
            if last_oxygen is None:  # 初始化血氧值
                oxygen = random.uniform(data_ranges["valid_oxygen"][0], data_ranges["valid_oxygen"][1])
            else:
                # 平滑变化：基于上一次值，增加小范围随机波动
                oxygen = last_oxygen + random.uniform(-1, 1)
                oxygen = max(data_ranges["generated_oxygen"][0], min(data_ranges["generated_oxygen"][1], oxygen))

            # 更新上一次的值
            last_pulse = pulse
            last_oxygen = oxygen

            current_time = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")

            valid, error_pulse, error_oxygen = validate_sensor_data(pulse, oxygen)

            # 准备日志信息
            message = f"[{current_time}] - {tag} - 脉搏: {pulse:.2f}次/分, 血氧: {oxygen:.2f}%"
            error_message = f"[{current_time}] - {tag} - 异常数据: 脉搏={pulse:.2f}次/分, 血氧={oxygen:.2f}%"

            # 写入文件
            with file_lock:
                try:
                    with open(file_path, "a") as file:
                        if valid:
                            file.write(message + "\n")
                        else:
                            file.write(f"{error_message}\n")
                except IOError as e:
                    logging.error(f"[{tag}] 文件写入失败: {e}")

            # 将消息放入队列
            if valid:
                log_queue.put(message)
            else:
                log_queue.put(error_message)

        time.sleep(5)  # 模拟传感器更新频率

# 示例入口函数
def main():
    # 设置文件路径和标签
    file_path = "output/sensor_output.csv"
    tag = "Device"

    # 初始化队列
    log_queue = queue.Queue()

    # 线程运行标志
    running_flag = [True]
    pause_flag = [False]  # 新增暂停标志

    # 启动数据生成线程
    threads = []
    for i in range(5):  # 启动5个线程作为示例
        sensor_thread = threading.Thread(target=generate_sensor_readings, 
                                        args=(file_path, log_queue, f"{tag}_{i}", running_flag, pause_flag), 
                                        name=f"{tag}_Thread_{i}")
        sensor_thread.start()
        threads.append(sensor_thread)

    # 控制程序退出（例如通过键盘输入等）
    try:
        input("按 Enter 键退出程序...\n")
    finally:
        running_flag[0] = False
        for thread in threads:
            thread.join()

    print("程序已退出。")

if __name__ == "__main__":
    main()